# -*- coding=utf-8
from forward.exceptions.base import AppException
from forward.http_base import HttpResp
from forward.utils.config import ConfigUtil
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.common import credential
from tencentcloud.cvm.v20170312 import models, cvm_client
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile


class QCloudStorage(object):
    engine = 'qcloud'

    async def get_client(self, **kwargs):
        """
        :param kwargs:
        :return:
        """
        try:
            self.config = await ConfigUtil.get_map("storage", 'qcloud')
            if self.config is None:
                raise AppException(HttpResp.FAILED, msg="配置文件不存在")
            self.bucket = self.config.get("bucket", "")
            secret_id = self.config.get("accessKey", "")
            secret_key = self.config.get("secretKey", "")
            region = self.config.get("region", "")
            token = None  # 如果使用临时密钥，需要传入 Token，默认为空
            cred = credential.Credential(
                secret_id=secret_id, secret_key=secret_key, token=token)
            # 实例化一个http选项，可选的，没有特殊需求可以跳过。
            httpProfile = HttpProfile()
            # 如果需要指定proxy访问接口，可以按照如下方式初始化hp
            # httpProfile = HttpProfile(proxy="http://用户名:密码@代理IP:代理端口")
            # 在外网互通的网络环境下支持http协议(默认是https协议),建议使用https协议
            httpProfile.protocol = "https"
            httpProfile.keepAlive = True  # 状态保持，默认是False
            httpProfile.reqMethod = "GET"  # get请求(默认为post请求)
            httpProfile.reqTimeout = 30    # 请求超时时间，单位为秒(默认60秒)
            # 指定接入地域域名(默认就近接入)
            httpProfile.endpoint = "cvm.ap-shanghai.tencentcloudapi.com"

            # 实例化一个client选项，可选的，没有特殊需求可以跳过。
            clientProfile = ClientProfile()
            clientProfile.signMethod = "TC3-HMAC-SHA256"  # 指定签名算法
            clientProfile.language = "en-US"  # 指定展示英文（默认为中文）
            clientProfile.httpProfile = httpProfile

            # 实例化要请求产品(以cvm为例)的client对象，clientProfile是可选的。
            client = cvm_client.CvmClient(cred, "ap-shanghai", clientProfile)
            return client
        except Exception as e:
            raise AppException(HttpResp.FAILED, msg=str(e))

    async def upload_data(self, target_path, data, **kwargs):
        """
        通过stream上传到腾讯云对象存储
        :param target_path:  目标路径，即文档参数key
        :param data:    stream
        :param kwargs:
        :return:
        """
        client = await self.get_client()
        try:
            # 实例化一个cvm实例信息查询请求对象,每个接口都会对应一个request对象。
            req = models.DescribeInstancesRequest()

            # 填充请求参数,这里request对象的成员变量即对应接口的入参。
            # 您可以通过官网接口文档或跳转到request对象的定义处查看请求参数的定义。
            respFilter = models.Filter()  # 创建Filter对象, 以zone的维度来查询cvm实例。
            respFilter.Name = "zone"
            respFilter.Values = ["ap-shanghai-1", "ap-shanghai-2"]
            req.Filters = [respFilter]  # Filters 是成员为Filter对象的列表

            # python sdk支持自定义header如 X-TC-TraceId、X-TC-Canary，可以按照如下方式指定，header必须是字典类型的
            headers = {
                "X-TC-TraceId": "ffe0c072-8a5d-4e17-8887-a8a60252abca"
            }
            req.headers = headers

            # 通过client对象调用DescribeInstances方法发起请求。注意请求方法名与请求对象是对应的，headers为可选参数。
            # 返回的resp是一个DescribeInstancesResponse类的实例，与请求对象对应。
            resp = client.DescribeInstances(req)
            return resp.to_json_string()
        except TencentCloudSDKException as e:
            raise AppException(HttpResp.FAILED, msg=str(e))
